package com.pww.movie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pww.movie.domain.DTO.MediaDto;
import com.pww.movie.domain.PO.Media;
import com.pww.movie.mapper.MediaMapper;
import com.pww.movie.service.IMediaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pww.movie.utils.MinioUploadUtil;
import com.pww.movie.utils.Result;
import com.pww.movie.utils.ThreadLocalUtil;
import com.pww.movie.utils.UploadBase64Image2MinioUtil;
import io.minio.MinioClient;
import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * 媒体资源表 服务实现类
 * </p>
 *
 * @author pww
 * @since 2025-06-09
 */
@Slf4j
@Service
@AllArgsConstructor
public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements IMediaService {

    private final MediaMapper mediaMapper;


    private final MinioClient minioClient;


    private final MinioUploadUtil minioUploadUtil;

    private final UploadBase64Image2MinioUtil uploadBase64Image2MinioUtil;

    private final RedisTemplate<String, String> redisTemplate;


    private final String BUCKET_NAME = "dairy-minio";
    private final String ENDPOINT = "http://192.168.31.181:9000";

    @PostConstruct
    public void initBucket() throws Exception {
        minioUploadUtil.initBucket(minioClient, BUCKET_NAME);
    }

    /**
     * 上传轮播图
     *
     * @param file
     * @param title
     * @param type
     * @param isBanner
     * @param createId
     * @param description
     * @return
     */
    @Override
    public String uploadBanner(MultipartFile file, String title, String type, Boolean isBanner, Integer createId, String description, String coverImage) {
        String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
        String imageUrl = null;
        String coverUrl = null;
        try {
            imageUrl = minioUploadUtil.uploadFile(minioClient, BUCKET_NAME, file, fileName, ENDPOINT);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (coverImage != null) {
            try {
                coverUrl = uploadBase64Image2MinioUtil.uploadBase64Image2Minio(coverImage, BUCKET_NAME, ENDPOINT);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        Media media = new Media();
        //0 表示轮播图
        media.setType(type);
        media.setUrl(imageUrl);
        media.setTitle(title);
        media.setCreatorId(createId.longValue());
        media.setIsBanner(isBanner);
        media.setDescription(description);
        media.setDeleted(false);
        media.setCreatedTime(LocalDateTime.now());
        media.setCoverImage(coverUrl);
        mediaMapper.insert(media);
        return imageUrl;
    }

    /**
     * 获取最新轮播图
     *
     * @return
     */
    @Override
    public List<Media> getLatestBanners() {
        QueryWrapper<Media> query = new QueryWrapper<>();
        query.eq("type", "0");
        query.eq("is_banner", true);
        query.orderByDesc("create_time");
        query.last("LIMIT 7");
        return mediaMapper.selectList(query);
    }

    /**
     * 获取最新轮播图
     *
     * @return
     */
    @Override
    public List<Media> getLatestBannersWithUserLike(Long createId) {
        LambdaQueryWrapper<Media> wrapper = new LambdaQueryWrapper<Media>()
                .eq(Media::getType, "image")
                .eq(Media::getIsBanner, 0)
                .eq(Media::getCreatorId, createId)
                .orderByDesc(Media::getCreatedTime)
                .last("LIMIT 7");
        return mediaMapper.selectList(wrapper);
    }

    /**
     * 获取用户收藏的媒体资源
     *
     * @param userId
     * @return
     */
    @Override
    public Result<List<Media>> getUserLike(Long userId) {
        List<Media> media = mediaMapper.selectList(new LambdaQueryWrapper<Media>()
                .eq(Media::getCreatorId, userId)
                .eq(Media::getIsBanner, 2)
                .orderByDesc(Media::getCreatedTime)
                .last("LIMIT 20"));
        return Result.success(media);
    }


    /**
     * 获取用户20的视频
     *
     * @param userId
     * @return
     */
    @Override
    public Result<List<Media>> getUserLikeVideo(Long userId) {
        List<Media> mediaList = mediaMapper.selectList(new LambdaQueryWrapper<Media>()
                .eq(Media::getCreatorId, userId)
                .eq(Media::getType, "video")
                .orderByDesc(Media::getCreatedTime)
                .last("LIMIT 20"));
        return Result.success(mediaList);
    }

    /**
     * 获取用户图片
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Result<Page<MediaDto>> getUserPicture(Integer pageNum, Integer pageSize) {
        Page<Media> page = new Page<>(pageNum, pageSize);
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        log.info("id: {}", id);
        Page<Media> pg = mediaMapper.selectPage(page, new LambdaQueryWrapper<Media>().eq(Media::getCreatorId, id).eq(Media::getType, "image").orderByDesc(
                Media::getCreatedTime));

        //构建新的分页
        Page<MediaDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(pg, dtoPage, "records");

        //获取key
        String key = getUserLikeKey(Long.valueOf(id));
        log.info("key: {}", key);
        //从redis中获取当前用户的喜欢记录
        Set userLikes = redisTemplate.opsForSet().members(key);
        log.info("userLikes: {}", userLikes);
        // 构建 DTO 列表
        List<MediaDto> dtoList = pg.getRecords().stream().map(media -> {
            MediaDto dto = new MediaDto(media);
            String value = media.getType() + ":" + media.getId(); // 如 image:20
            dto.setLiked(userLikes != null && userLikes.contains(value));
            return dto;
        }).collect(Collectors.toList());
        dtoPage.setRecords(dtoList);
        return Result.success(dtoPage);
    }

    /**
     * 获取用户视频
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Result<Page<MediaDto>> getUserVideo(Integer pageNum, Integer pageSize) {
        System.out.println("pageNum = " + pageNum + ", pageSize = " + pageSize);
        Page<Media> page = new Page<>(pageNum, pageSize);
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        Page<Media> videoPage = mediaMapper.selectPage(page, new LambdaQueryWrapper<Media>().eq(Media::getCreatorId, userId).eq(Media::getType, "video"));
        Page<MediaDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(videoPage, dtoPage, "records");
        Set<String> userLike = redisTemplate.opsForSet().members(getUserLikeKey(Long.valueOf(userId)));
        List<MediaDto> dtoList = videoPage.getRecords().stream().map(video -> {
            MediaDto dto = new MediaDto(video);
            String value = video.getType() + ":" + video.getId();
            dto.setLiked(userLike != null && userLike.contains(value));
            return dto;
        }).collect(Collectors.toList());
        dtoPage.setRecords(dtoList);
        return Result.success(dtoPage);
    }


    private String getUserLikeKey(Long userId) {
        return "like:user:" + userId;
    }

}
